package com.cjd.common.utils

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import java.io.BufferedOutputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream

/**
 * @Author chenjidong
 * @email 374122600@qq.com
 * created 2017-04-14.
 * description
 */
object CompressPhotoUtils {

    /**
     * 压缩图片尺寸
     *
     * @param pathName
     * @param targetWidth
     * @param targetHeight
     * @return
     */
    fun compressByFile(
        pathName: String, targetWidth: Int,
        targetHeight: Int
    ): Bitmap {
        val opts = BitmapFactory.Options()
        opts.inJustDecodeBounds = true
        var bitmap = BitmapFactory.decodeFile(pathName, opts)

        opts.inSampleSize = calculateInSampleSize(opts, targetWidth, targetHeight)
        opts.inJustDecodeBounds = false
        bitmap = BitmapFactory.decodeFile(pathName, opts)
        return bitmap
    }

    /**
     * 存储进SD卡
     *
     * @param bm
     * @param fileName
     * @throws Exception
     */
    @Throws(Exception::class)
    fun saveFile(bm: Bitmap, fileName: String) {
        val dirFile = File(fileName)

        if (dirFile.exists()) {
            dirFile.delete()
        }
        val myCaptureFile = File(fileName)
        val bos = BufferedOutputStream(FileOutputStream(myCaptureFile))
        bm.compress(Bitmap.CompressFormat.JPEG, 100, bos)
        bos.flush()
        bos.close()
    }

    /**
     * 根据传入的宽和高，计算出合适的inSampleSize值
     *
     * @param options
     * @param reqWidth  需要的宽
     * @param reqHeight 需要的高
     * @return
     */
    fun calculateInSampleSize(
        options: BitmapFactory.Options,
        reqWidth: Int, reqHeight: Int
    ): Int {
        val height = options.outHeight
        val width = options.outWidth
        var inSampleSize = 1
        if (height > reqHeight || width > reqWidth) {
            val heightRatio = Math.round(height.toFloat() / reqHeight.toFloat())
            val widthRatio = Math.round(width.toFloat() / reqWidth.toFloat())
            inSampleSize = if (heightRatio < widthRatio) heightRatio else widthRatio
        }
        return inSampleSize
    }

    fun getDiskBitmap(pathString: String): Bitmap? {
        var bitmap: Bitmap? = null
        try {
            val file = File(pathString)
            if (file.exists()) {
                bitmap = BitmapFactory.decodeFile(pathString)
            }
        } catch (e: Exception) {
            // TODO: handle exception
        }


        return bitmap
    }

    /**
     * @param path    原图路径
     * @param offsetX 截取开始点在X轴偏移量
     * @param offsetY 截取开始点在Y轴偏移量
     * @param targetW 截取多宽（像素）
     * @param targetH 截取多高（像素）
     * @return
     */
    fun matrixScale(path: String, offsetX: Int, offsetY: Int, targetW: Int, targetH: Int): Bitmap {
        // 构建原始位图
        var bitmap = BitmapFactory.decodeFile(path)
        // 获取原始宽高
        val width = bitmap.width
        val height = bitmap.height
        // 计算宽高缩放比例，targetW，targetH即期待缩放完成后位图的宽高
        val scaleW = targetW.toFloat() / width
        val scaleH = targetH.toFloat() / height
        // 将缩放比例放进矩阵
        val matrix = Matrix()
        matrix.postScale(scaleW, scaleH)
        // 这个方法作用非常多，详细解释一下各个参数的意义！
        // bitmap：原始位图
        // 第二到第五个参数，即截取原图哪一部分构建新位图，
        // offsetX和offsetY代表在X轴和Y轴上的像素偏移量，即从哪个位置开始截取
        // width和height代表截取多少个像素，但是要注意，offsetX+width应该小于等于原图的宽度
        // offsetY+height小于等于原图高度，要不然会报错，因为截到原图外面去了
        // 像下面这样填写，就代表截取整个原图，
        // Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
        // 如果填写100,100,200,200，就代表
        // 从原图左上角往右和下各偏移100像素，然后往后和往下各截取200构建新位图
        // matrix：缩放矩阵
        // 最后一个参数表示如果矩阵里面还存放了过滤条件，是否按条件过滤（如果matrix里面只放了平移数据），最后一个参数设置成什么都不会生效
        bitmap = Bitmap.createBitmap(bitmap, offsetX, offsetY, width, height, matrix, false)
        return bitmap
    }

    /**
     * @param path    图片路径
     * @param quality 质量 0-100,100表示原图
     * @return
     */
    fun losslessScale(path: String, quality: Int): Bitmap {
        val bitmap = BitmapFactory.decodeFile(path)
        val baos = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos)

        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos)
        LogUtils.d("losslessScale 最终大小" + baos.toByteArray().size)
        return BitmapFactory.decodeByteArray(
            baos.toByteArray(), 0, baos.toByteArray().size
        )
    }

    fun bitmapToByteArray(bitmap: Bitmap?): ByteArray? {
        if (bitmap == null)
            return null
        val baos = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos)
        return baos.toByteArray()
    }
}